<!-- 主题设置模板 -->

<script type="text/html" template lay-done="layui.data.sendParams(d.params);">

  <div class="layui-upload-drag" style="display: block;" id="ID-upload-drag">
    <i class="layui-icon layui-icon-upload"></i> 
    <div>点击上传，或将文件拖拽到此处</div>
    <div class="layui-hide" id="ID-upload-demo-preview">
      <hr> <img src="" alt="上传成功后渲染" style="max-width: 100%">
    </div>
  </div>

</script>
<script>

  //定义一个 lay-done 对应的全局方法，以供动态模板执行
  layui.data.sendParams = function (params) {
    let { viewId, ...param } = params;
    viewId = viewId || 'appId';

    //通过得到的参数值，做一些你想做的事
    //…

    //若需用到 layui 组件，layui.use 需写在该全局方法里面，如：
    layui.use(['admin', 'upload', 'fileServiceApi'], function () {

      var upload = layui.upload;
      var $ = layui.$;

      var fileServiceApi = layui.fileServiceApi;
      let data = param.item;
      let imgType = param.imgType;

      function showimg(imageFile) {
        const resultImage = document.createElement('img');
        resultImage.style.display = 'none';
        document.body.appendChild(resultImage);

        resultImage.src = URL.createObjectURL(imageFile);
        resultImage.style.display = 'block';

        URL.revokeObjectURL(resultImage.src);
        document.body.removeChild(resultImage);
      }

      // 上传视频帧作为封面
      async function UploadVideoFrame(file, type) {
        let imageFile = await captureVideoFrame(file, type);

        let re = await fileServiceApi.uploadFile(imageFile);
        data.img = re.data.remoteUrl;

        layer.load(1, {
          shade: [0.1, '#000'] // 0.1 透明度的白色背景
        });
      }

      //截取视频帧
      async function captureVideoFrame(file, type) {
        return new Promise(async (resolve, reject) => {
          if (!file.type.startsWith('video/')) {
            reject(new Error('文件不是视频文件'));
            return;
          }

          const video = document.createElement('video');
          video.src = URL.createObjectURL(file);
          video.preload = 'auto'; // 确保视频提前加载
          video.muted = true; // 避免自动播放声音
          video.autoplay = true;

          const canvas = document.createElement('canvas');
          const context = canvas.getContext('2d');

          let targetWidth, targetHeight;
          if (type === 2) {
            targetWidth = 554;
            targetHeight = 960;
          } else if (type === 1) {
            targetWidth = 672;
            targetHeight = 378;
          } else {
            reject(new Error('无效的类型'));
            return;
          }

          video.addEventListener('loadedmetadata', () => {
            // 设置截图时间点为3秒
            video.currentTime = 3;
          });

          video.addEventListener('seeked', () => {
            canvas.width = targetWidth;
            canvas.height = targetHeight;

            // 确保视频帧加载完成
            requestAnimationFrame(() => {
              requestAnimationFrame(() => {
                context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, targetWidth, targetHeight);
                canvas.toBlob(async (blob) => {
                  const imageFile = new File([blob], "video_img.jpg", { type: 'image/jpg' });
                  try {
                    resolve(imageFile);
                  } catch (error) {
                    reject(error);
                  } finally {
                    URL.revokeObjectURL(video.src);

                  }
                }, 'image/jpg');
              });
            });
          });

          video.addEventListener('error', () => {
            reject(new Error('视频加载失败'));
          });
        });
      }

      //获取文件名
      function getFileName(url) {
        return url.split('/').pop();
      }

      //计算文件的SHA256哈希值
      async function sha256(file) {
        let sha256 = CryptoJS.algo.SHA256.create();
        const sliceSize = 10 * 1024 * 1024; // 10 MiB
        let start = 0;

        while (start < file.size) {
          const slice = await readSlice(file, start, sliceSize);
          const wordArray = CryptoJS.lib.WordArray.create(slice);
          sha256 = sha256.update(wordArray);
          start += sliceSize;
        }

        sha256.finalize();
        return sha256._hash.toString();
      }

      //读取文件片
      async function readSlice(file, start, size) {
        return new Promise((resolve, reject) => {
          const fileReader = new FileReader();
          const slice = file.slice(start, start + size);

          fileReader.onload = () => resolve(new Uint8Array(fileReader.result));
          fileReader.onerror = reject;
          fileReader.readAsArrayBuffer(slice);
        });
      }

      // 渲染
      upload.render({
        elem: '#ID-upload-drag',
        url: '/Uploader/Upload', // 实际使用时改成您自己的上传接口即可。
        accept: 'video',
        auto: false,
        acceptMime: 'video/*',
        choose: function (obj) {

          //超过100m的大文件无法计算
          var files = obj.pushFile();

          obj.preview(async function (index, file) {
            // 显示加载提示
            layer.load(2, {
              shade: [0.1, '#000'] // 0.1 透明度的白色背景
            });

            const fileSize = file.size;
            //获取文件的SHA256哈希值
            //并截取第3秒的画面并保存
            const [imageFile, sha256Hash] = await Promise.all([
              UploadVideoFrame(file, imgType), // 获取视频帧
              sha256(file) // 计算文件的 SHA256 哈希值
            ]);

            let re = await fileServiceApi.checkFileExists(fileSize, sha256Hash);
            if (re.data.isExists) {
              // layer.msg('文件已存在，无需重复上传');
              // delete files[index];

              data.fileUrl = re.data.url;
              data.fileName = getFileName(data.fileUrl);
              params.upVideo(data);
              layer.closeAll('loading');
            } else {
              layer.closeAll('loading');
              //layer.msg('文件不存在，可以继续上传');
              obj.upload(index, file);
            }

          });

        },
        before: function (obj) {
          // 显示加载提示
          layer.load(1, {
            shade: [0.1, '#000'] // 0.1 透明度的白色背景
          });


        },
        done: function (res) {
          // 隐藏加载提示
          layer.closeAll('loading');

          console.log("调用了上传");
          if (res.code === 0) { // 假设 res.code === 0 表示上传成功
            data.fileUrl = res.data.remoteUrl;
            data.fileName = res.data.fileName;

            //console.log(data);
            params.upVideo(data);
          } else {
            layer.msg('上传失败: ' + res.msg);
          }
        },
        error: function () {
          // 隐藏加载提示
          layer.closeAll('loading');
          layer.msg('上传失败，请检查网络或文件格式');
        }
      });

    });
  };
</script>